--- title: "L2-027 名人堂与代金券" created: 2025-11-28 tags: - 算法 --- # L2-027 名人堂与代金券 ## 题目 [L2-027 名人堂与代金券](https://pintia.cn/problem-sets/994805046380707840/exam/problems/type/7?problemSetProblemId=994805055176163328&page=1) ![[image-bb54e88b.png]] ## 思路分析 ![[image-3c1659bf.png]] 主要是并列排名难处理 排名为并列时,跳跃排名,比如: 分数:100, 100, 99 → 排名为 1, 1, 3(因为两个100并列第一,下一个就是第三名) ```cpp int current_rank=1; hall.push_back({current_rank,students[0].name,students[0].score}); ``` 第一个人默认是第1名 ```cpp for(int i=1;i k) break; hall.push_back({current_rank, students[i].name, students[i].score}); } ``` i+1 表示的是第几个学生,因为数组从 0 开始 如果当前学生分数和前一个学生不一样,就更新排名为 i+1 如果一样分数,排名不变 由于排名可能会跳过中间值(并列情况),比如: | i | 分数 | 当前排名 | | --- | --- | --- | | 0 | 100 | 1 | | 1 | 100 | 1 | | 2 | 98 | 3 | | 3 | 97 | 4 | 排名就形成了“并列+跳跃”的机制。 核心在于 维护原本排名和并列排名两个东西 原本排名用i递增维护 并列排名由上一个人的排名维护 ## 代码实现 ```cpp #include using namespace std; #define endl '\n' using ll = long long; using ull = unsigned long long; using PII = pair; using Pll = pair; int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1}; struct Student{ string name; int score; bool operator<(const Student& rhs) const{ if(score != rhs.score) return score>rhs.score; return name>n>>g>>k; vector students(n); int total=0; for(int i=0;i>students[i].name>>students[i].score; if(students[i].score>=g) total+=50; else if(students[i].score>=60) total+=20; } cout< hall; int current_rank=1; hall.push_back({current_rank,students[0].name,students[0].score}); for(int i=1;ik) break; hall.push_back({current_rank,students[i].name,students[i].score}); } for(auto v:hall){ cout<